package communication;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.security.cert.X509Certificate;

import storageclasses.Bank;

public class Server implements Runnable {
	private Bank bank;
	private String[][] personellMatrix;

	private LoginInfo init(LoginInfo li) {
		String keystore_name = System.getProperty("javax.net.ssl.keyStore");
		li.KEYSTORE_NAME = keystore_name;

		String keystore_password = System
				.getProperty("javax.net.ssl.keyStorePassword");
		li.KEYSTORE_PW = keystore_password;

		String truststore_name = System.getProperty("javax.net.ssl.trustStore");
		li.TRUSTSTORE_NAME = truststore_name;

		String truststore_password = System
				.getProperty("javax.net.ssl.trustStorePassword");
		li.TRUSTSTORE_PW = truststore_password;

		// System.out.print("Reading keystore from: ");
		// System.err.print(keystore_name);
		// System.out.print(" with password: ");
		// System.err.println(keystore_password);
		//		
		// System.out.print("Reading truststore from: ");
		// System.err.print(truststore_name);
		// System.out.print(" with password: ");
		// System.err.println(truststore_password);
		return li;
	}

	public Server(Bank bank, String[][] personellMatrix) {
		this.bank = bank;
		this.personellMatrix = personellMatrix;
		newListener();
	}

	public void run() {
		// -Djavax.net.ssl.keyStore=david_keystore
		// -Djavax.net.ssl.keyStorePassword=daviddavid
		//
		// -Djavax.net.ssl.trustStore=ca_truststore
		// -Djavax.net.ssl.trustStorePassword=trustword

		// System.setProperty("javax.net.ssl.keyStore", "david_keystore");
		// System.setProperty("javax.net.ssl.keyStorePassword",
		// "daviddavid");
		//		
		// System.setProperty("javax.net.ssl.trustStore", "ca_truststore");
		// System.setProperty("javax.net.ssl.trustStorePassword",
		// "trustword");

		LoginInfo li = new LoginInfo();
		init(li);

		try {
			int port = 1337;
			ServerSocketFactory ssocketFactory = SSLServerSocketFactory
					.getDefault();
			SSLServerSocket ssocket = (SSLServerSocket) ssocketFactory
					.createServerSocket(port);

			// Listen for connections
			ssocket.setNeedClientAuth(true);

			while (true) {
				SSLSocket socket = (SSLSocket) ssocket.accept();
				SSLSession session = socket.getSession();
				X509Certificate cert = (X509Certificate) session
						.getPeerCertificateChain()[0];
				String subject = cert.getSubjectDN().getName();
				System.out.println(subject);

				li = extractInfo(li, subject);

				System.out.println(li.toString());

				// Create streams to securely send and receive data to the
				// client
				InputStream in = socket.getInputStream();
				OutputStream out = socket.getOutputStream();

				// Read from in and write to out...
				byte[] data = new byte[10000];
				int size = in.read(data);
				byte[] response = new CommandParser(data, size, li).getResponse(bank,
						 personellMatrix);
				 out.write(response);

				// Close the socket
				in.close();
				out.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void newListener() {
		(new Thread(this)).start();
	}

	private LoginInfo extractInfo(LoginInfo li, String subject) {
		li.LOGIN_NAME = subject.split(",")[0].substring(3);
		li.LOGIN_PRSNBR = subject.split(",")[1].substring(4);
		return li;
	}

}
